package cn.xspace.wnx.activity;

import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.TextView;

import com.amap.api.location.AMapLocation;
import com.amap.api.location.AMapLocationClient;
import com.amap.api.location.AMapLocationClientOption;
import com.amap.api.location.AMapLocationListener;
import com.amap.api.maps2d.AMap;
import com.amap.api.maps2d.CameraUpdateFactory;
import com.amap.api.maps2d.model.BitmapDescriptorFactory;
import com.amap.api.maps2d.model.CameraPosition;
import com.amap.api.maps2d.model.LatLng;
import com.amap.api.maps2d.model.Marker;
import com.amap.api.maps2d.model.MarkerOptions;
import com.amap.api.maps2d.overlay.PoiOverlay;
import com.amap.api.services.core.AMapException;
import com.amap.api.services.core.LatLonPoint;
import com.amap.api.services.core.PoiItem;
import com.amap.api.services.geocoder.GeocodeSearch;
import com.amap.api.services.geocoder.RegeocodeAddress;
import com.amap.api.services.geocoder.RegeocodeQuery;
import com.amap.api.services.help.Inputtips;
import com.amap.api.services.help.InputtipsQuery;
import com.amap.api.services.help.Tip;
import com.amap.api.services.poisearch.PoiResult;
import com.amap.api.services.poisearch.PoiSearch;
import com.xspace.android.xafcommon.base.BaseMapActivity;
import com.xspace.android.xafcommon.util.T;
import com.xspace.android.xafcommon.view.XListView;

import java.util.ArrayList;
import java.util.List;

import cn.xspace.wnx.R;
import cn.xspace.wnx.adapter.MapSearchListAdapter;
import rx.Observable;
import rx.Subscriber;
import rx.android.schedulers.AndroidSchedulers;
import rx.schedulers.Schedulers;

public class MapLocationSelectActivity extends BaseMapActivity implements AMap.OnCameraChangeListener,
        AMapLocationListener, TextWatcher, Inputtips.InputtipsListener, XListView.IXListViewListener {

    private Marker locationMarker;
    private OnLocationChangedListener mListener;
    private LatLng locationLatLng;

    AMap.InfoWindowAdapter infoWindowAdapter = new AMap.InfoWindowAdapter() {

        @Override
        public View getInfoWindow(Marker marker) {
            return null;
        }

        @Override
        public View getInfoContents(Marker marker) {
            View mContents = getLayoutInflater().inflate(R.layout.custom_info_contents, null);
            render(marker, mContents);
            return mContents;
        }
    };
    private String cityCode;
    private MapSearchListAdapter mAdapter;
    private boolean mIsLoadMore;

    /**
     * 自定义infowindow的样式
     */
    public void render(Marker marker, View view) {
        String title = marker.getTitle();
        TextView titleUi = ((TextView) view.findViewById(R.id.title));
        if (title != null) {
            titleUi.setText(title);
        } else {
            titleUi.setText("");
        }
        String snippet = marker.getSnippet();
        TextView snippetUi = ((TextView) view.findViewById(R.id.snippet));
        if (snippet != null) {
            snippetUi.setText(snippet);
        } else {
            snippetUi.setText("");
        }
    }

    @Override
    protected void setUpMap() {
        aMap.setOnCameraChangeListener(this);
        aMap.setInfoWindowAdapter(infoWindowAdapter);
        aMap.setLocationSource(this);// 设置定位监听
        aMap.getUiSettings().setMyLocationButtonEnabled(true);// 设置默认定位按钮是否显示
        aMap.setMyLocationEnabled(true);// 设置为true表示显示定位层并可触发定位，false表示隐藏定位层并不可触发定位，默认是false
    }

    @Override
    protected void initTitleBar() {
        mTitleBar.setTitle("获取位置信息");
        mTitleBar.setRightFilterVisibility(View.VISIBLE);
        mTitleBar.setFilterImageResource(R.drawable.icon_common_search);
    }

    @Override
    protected void initEventNew() {
        mTitleBar.setLeftLayoutClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                actionBackPress();
            }
        });
        mTitleBar.setFilterClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                showSearchLayout();
            }
        });
        mTitleBar.setRightLayoutClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

            }
        });
        mTvMapSearch.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String keyWord = mEtMapSearch.getText().toString().trim();
                if (TextUtils.isEmpty(keyWord)) {
                    T.showSingleL("请输入搜索关键字");
                } else {
                    doSearchQuery();
                }
            }
        });
        mEtMapSearch.addTextChangedListener(this);// 添加文本输入框监听事件
    }

    private void actionBackPress() {
        if (mRelativeSearchResult.getVisibility() == View.VISIBLE) {
            hiddenSearchLayout();
        } else {
            finish();
        }
    }

    @Override
    public void onBackPressed() {
        actionBackPress();
    }

    private PoiSearch.Query query;
    private int currentPage;
    private PoiSearch poiSearch;
    private PoiResult poiResult;
    private List<PoiItem> mDataList = new ArrayList<>();

    PoiSearch.OnPoiSearchListener onPoiSearchListener = new PoiSearch.OnPoiSearchListener() {
        @Override
        public void onPoiSearched(PoiResult result, int rCode) {
            hideWaitDialog();
//            hiddenSearchLayout();
            if (rCode == AMapException.CODE_AMAP_SUCCESS) {
                if (result != null && result.getQuery() != null) {// 搜索poi的结果
                    if (result.getQuery().equals(query)) {// 是否是同一条
                        poiResult = result;
                        // 取得搜索到的poiItems有多少页
                        List<PoiItem> poiItems = poiResult.getPois();// 取得第一页的poiItems数据，页数从数字0开始
                        // 当搜索不到poiItems数据时，会返回含有搜索关键字的城市信息
//                        List<SuggestionCity> suggestionCities = poiResult.getSearchSuggestionCitys();

                        if (poiItems != null && poiItems.size() > 0) {
                            mDataList.clear();
                            mDataList.addAll(poiItems);
                            showSearchList();
                            aMap.clear();// 清理之前的图标
                            PoiOverlay poiOverlay = new PoiOverlay(aMap, poiItems);
                            poiOverlay.removeFromMap();
                            poiOverlay.addToMap();
                            poiOverlay.zoomToSpan();
                        }/* else if (suggestionCities != null && suggestionCities.size() > 0) {
                            showSuggestCity(suggestionCities);
                        }*/ else {
                            T.showSingleL("没有结果");
                        }
                    }
                } else {
                    T.showSingleL("没有结果");
                }
            } else {
                T.showSingleL("请求失败");
            }
        }

        @Override
        public void onPoiItemSearched(PoiItem poiItem, int i) {

        }
    };

    private void showSearchList() {
        if (mAdapter == null) {
            mAdapter = new MapSearchListAdapter(mContext, mDataList);
            mXLvMapResult.setAdapter(mAdapter);
            mXLvMapResult.setXListViewListener(this);
            mXLvMapResult.setPullLoadEnable(true);
            mXLvMapResult.setPullRefreshEnable(false);
            mXLvMapResult.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                @Override
                public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

                }
            });
        } else {
            mAdapter.notifyDataSetChanged();
        }
    }

    private void refreshList() {
//        mPullToRefreshListView.onRefreshComplete();
        if (mAdapter != null) {
            mXLvMapResult.stopRefresh();
            mXLvMapResult.stopLoadMore();
            mAdapter.notifyDataSetChanged();
            mIsLoadMore = false;
        }
    }

    /**
     * 开始进行poi搜索
     */
    protected void doSearchQuery() {
        String keyWord = mEtMapSearch.getText().toString().trim();
        showWaitDialog();
        currentPage = 0;
        query = new PoiSearch.Query(keyWord, "", cityCode);//
        // 第一个参数表示搜索字符串，第二个参数表示poi搜索类型，第三个参数表示poi搜索区域（空字符串代表全国）
        query.setPageSize(10);// 设置每页最多返回多少条poiitem
        query.setPageNum(currentPage);// 设置查第一页
        query.setCityLimit(true);

        poiSearch = new PoiSearch(this, query);
        poiSearch.setOnPoiSearchListener(onPoiSearchListener);
        poiSearch.searchPOIAsyn();
    }

    @Override
    public void activate(OnLocationChangedListener onLocationChangedListener) {
        mListener = onLocationChangedListener;
        if (mLocationClient == null) {
            mLocationClient = new AMapLocationClient(this);
            AMapLocationClientOption mLocationOption = new AMapLocationClientOption();
            //设置定位监听
            mLocationClient.setLocationListener(this);
            //设置为高精度定位模式
            mLocationOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);
            //设置定位参数
            mLocationClient.setLocationOption(mLocationOption);
            // 此方法为每隔固定时间会发起一次定位请求，为了减少电量消耗或网络流量消耗，
            // 注意设置合适的定位时间的间隔（最小间隔支持为2000ms），并且在合适时间调用stopLocation()方法来取消定位请求
            // 在定位结束后，在合适的生命周期调用onDestroy()方法
            // 在单次定位情况下，定位无论成功与否，都无需调用stopLocation()方法移除请求，定位sdk内部会移除
            mLocationClient.startLocation();
        }
    }

    @Override
    public void deactivate() {
        super.deactivate();
        mListener = null;
    }

    @Override
    public void onLocationChanged(AMapLocation aMapLocation) {
        if (mListener != null) {
            // 此处注释掉，表示不用系统提供的定位图标等
            // mListener.onLocationChanged(aLocation);
        }
        if (aMapLocation != null) {
            cityCode = aMapLocation.getCityCode();
            Double geoLat = aMapLocation.getLatitude();
            Double geoLng = aMapLocation.getLongitude();
            locationLatLng = new LatLng(geoLat, geoLng);

            aMap.clear();
            addMarker(locationLatLng, aMapLocation.getAddress());
            locationMarker.showInfoWindow();// 显示信息窗口
            aMap.moveCamera(CameraUpdateFactory.newLatLngZoom(locationLatLng, 15));
            deactivate();
        }
    }


    /**
     * 往地图上添加marker
     *
     * @param latLng
     */
    private void addMarker(LatLng latLng, String desc) {
        MarkerOptions markerOptions = new MarkerOptions();
        markerOptions.position(latLng);
        markerOptions.title("[我的位置]");
        markerOptions.snippet(desc);
        markerOptions.icon(BitmapDescriptorFactory.defaultMarker());
        locationMarker = aMap.addMarker(markerOptions);
    }

    @Override
    public void onCameraChange(CameraPosition position) {
        if (locationMarker != null) {
            LatLng latLng = position.target;
            locationMarker.setPosition(latLng);
        }
    }

    @Override
    public void onCameraChangeFinish(CameraPosition position) {
        if (locationMarker != null) {
            final LatLng latLng = position.target;
            Observable.create(new Observable.OnSubscribe<RegeocodeAddress>() {
                @Override
                public void call(Subscriber<? super RegeocodeAddress> subscriber) {
                    GeocodeSearch geocodeSearch = new GeocodeSearch(mContext);
                    LatLonPoint point = new LatLonPoint(latLng.latitude, latLng.longitude);
                    RegeocodeQuery regeocodeQuery = new RegeocodeQuery(point, 1000, GeocodeSearch.AMAP);
                    RegeocodeAddress address;
                    try {
                        address = geocodeSearch.getFromLocation(regeocodeQuery);
                        subscriber.onNext(address);
                    } catch (AMapException e) {
                        subscriber.onError(e);
                    }
                    subscriber.onCompleted();
                }
            }).subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread()).subscribe(new Subscriber<RegeocodeAddress>() {
                @Override
                public void onCompleted() {
                }

                @Override
                public void onError(Throwable throwable) {
                    throwable.printStackTrace();
                }

                @Override
                public void onNext(RegeocodeAddress address) {
                    if (null != address) {
                        locationMarker.setSnippet(address.getFormatAddress());
                    }
                    locationMarker.showInfoWindow();
                }
            });
        }
    }

    @Override
    public void beforeTextChanged(CharSequence s, int start, int count, int after) {

    }

    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count) {

    }

    @Override
    public void afterTextChanged(Editable s) {
        String newText = s.toString().trim();
        if (!TextUtils.isEmpty(newText)) {
            InputtipsQuery inputQuery = new InputtipsQuery(newText, cityCode);
            Inputtips inputTips = new Inputtips(mContext, inputQuery);
            inputTips.setInputtipsListener(this);
            inputTips.requestInputtipsAsyn();
        }
    }

    @Override
    public void onGetInputtips(List<Tip> tipList, int rCode) {
        if (rCode == AMapException.CODE_AMAP_SUCCESS) {// 正确返回
            List<String> listString = new ArrayList<String>();
            for (int i = 0; i < tipList.size(); i++) {
                listString.add(tipList.get(i).getName());
            }
            ArrayAdapter<String> aAdapter = new ArrayAdapter<>(mContext, android.R.layout.simple_list_item_1,
                    listString);
            mEtMapSearch.setAdapter(aAdapter);
            aAdapter.notifyDataSetChanged();
        } else {
            T.showSingleL("没有数据");
        }
    }

    @Override
    public void onRefresh() {

    }

    @Override
    public void onLoadMore() {
        if (!mIsLoadMore) {
            queryNext();
        }
    }

    public void queryNext() {
        if (query != null && poiSearch != null && poiResult != null) {
            if (poiResult.getPageCount() - 1 > currentPage) {
                currentPage++;
                query.setPageNum(currentPage);// 设置查后一页
                poiSearch.searchPOIAsyn();
            } else {
                T.showSingleL("没有结果");
            }
        }
    }
}
